{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Widgets"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "As we have seen in previous sections, hvPlot bakes in interactivity by automatically creating widgets when using ``groupby``. These widgets can be refined using [Panel](https://panel.holoviz.org). Panel allows you to customize the interactivity of your hvPlot output and provides more fine-grained control over the layout."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "<div class=\"alert alert-warning\" role=\"alert\">\n",
    "  When viewing on a static website, the widgets will be inoperable. To explore this functionality fully, download the notebook and run it!\n",
    "</div>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import panel as pn\n",
    "import hvplot.pandas  # noqa\n",
    "\n",
    "from bokeh.sampledata.iris import flowers\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When ``groupby`` is used, the default widget is selected for the data type of the column. In this case since 'species' is composed of strings, the widget an instance of the class ``pn.widgets.Select``."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "flowers.hvplot.bivariate(x='sepal_width', y='sepal_length', width=600, \n",
    "                         groupby='species')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Customizing Widgets\n",
    "\n",
    "We can change where the widget is shown using the ``widget_location`` option."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "flowers.hvplot.bivariate(x='sepal_width', y='sepal_length', width=600, \n",
    "                         groupby='species', widget_location='left_top')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also change what the class of the widget is, using the ``widgets`` dict. For instance if we want to use a slider instead of a selector we can specify that."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "flowers.hvplot.bivariate(x='sepal_width', y='sepal_length', width=600, \n",
    "                         groupby='species', widgets={'species': pn.widgets.DiscreteSlider})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using widgets as arguments\n",
    "\n",
    "So far we have only been dealing with widgets that are produced when using the ``groupby`` key word. But panel provides many other ways of expanding the interactivity of hvplot objects. For instance we might want to allow the user to select which fields to plot on the ``x`` and ``y`` axes. Or even what ``kind`` of plot to produce."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = pn.widgets.Select(name='x', options=['sepal_width', 'petal_width'])\n",
    "y = pn.widgets.Select(name='y', options=['sepal_length', 'petal_length'])\n",
    "kind = pn.widgets.Select(name='kind', value='scatter', options=['bivariate', 'scatter'])\n",
    "\n",
    "plot = flowers.hvplot(x=x, y=y, kind=kind, colorbar=False, width=600)\n",
    "pn.Row(pn.WidgetBox(x, y, kind), plot)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Using functions\n",
    "\n",
    "In addition to using widgets directly as arguments, we can also use functions that have been decorated with ``pn.depends``"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "x = pn.widgets.Select(name='x', options=['sepal_width', 'petal_width'])\n",
    "y = pn.widgets.Select(name='y', options=['sepal_length', 'petal_length'])\n",
    "kind = pn.widgets.Select(name='kind', value='scatter', options=['bivariate', 'scatter'])\n",
    "by_species = pn.widgets.Checkbox(name='By species')\n",
    "color = pn.widgets.ColorPicker(value='#ff0000')\n",
    "\n",
    "@pn.depends(by_species, color)\n",
    "def by_species_fn(by_species, color):\n",
    "    return 'species' if by_species else color\n",
    "\n",
    "plot = flowers.hvplot(x=x, y=y, kind=kind, c=by_species_fn, colorbar=False, width=600, legend='top_right')\n",
    "\n",
    "pn.Row(pn.WidgetBox(x, y, kind, color, by_species), plot)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can keep even add a callback to disable the color options when 'bivariate' is selected. After running the cell below, try changing 'kind' above and notice how the color and 'By species' areas turn grey to indicate that they are disabled."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "def update(event):\n",
    "    if kind.value == 'bivariate':\n",
    "        color.disabled = True\n",
    "        by_species.disabled = True\n",
    "    else:\n",
    "        color.disabled = False\n",
    "        by_species.disabled = False\n",
    "\n",
    "kind.param.watch(update, 'value');"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To learn more about Panel and how to use it with output from hvPlot, see the [Panel docs on the HoloViews pane](https://panel.pyviz.org/reference/panes/HoloViews.html). To learn more about available widgets, see the Widgets' section of the [Panel Reference Gallery](https://panel.pyviz.org/reference/index.html)."
   ]
  }
 ],
 "metadata": {
  "language_info": {
   "name": "python",
   "pygments_lexer": "ipython3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
